package com.ruoyi.web.ai;

import com.ruoyi.common.base.ai.domain.AIApiKey;
import com.ruoyi.common.base.ai.mapper.AIApiKeyMapper;
import com.ruoyi.common.base.ai.mapstruct.AIApiKeyStruct;
import com.ruoyi.common.base.ai.vo.AIApiKeyCache;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.SysConfigConstants;
import com.ruoyi.common.utils.EmailSender;
import com.ruoyi.system.service.ISysConfigService;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;

import static com.ruoyi.framework.datasource.DynamicDataSourceContextHolder.log;

/**
 * 动态获取ApiKey
 *
 * @author gdk
 * @since 2023/5/16 20:54
 */
@Data
@Component
@AllArgsConstructor
public class AIDynamicKey {
    private final RedisTemplate<String, Object> redis;
    private final AIApiKeyMapper aiApiKeyMapper;
    private final ISysConfigService sysConfigService;
    private final EmailSender emailSender;

    /**
     * 获取ApiKey
     *
     * @return {@link String}
     * @author gdk
     * @since 2023/5/29 16:33
     */
    public AIApiKeyCache getKey() {
        Object o = redis.opsForSet().randomMember(CacheConstants.AI_API_KEY_HASH_KEY);
        // 无视该语法检查告警
        if (Objects.isNull(o) && redis.opsForSet().size(CacheConstants.AI_API_KEY_HASH_KEY) == 0) {
            return null;
        }

        return (AIApiKeyCache) o;
    }

    /**
     * 邮件告警
     *
     * @author gdk
     * @since 2023/5/29 16:56
     */
    public void emailNotify(int warningLine, long size) {
        // 获取需要发送的邮件地址
        // String email = sysConfigService.selectConfigByKey(SysConfigConstants.AI_CHAT_API_KEY_WARNING_EMAIL, "1036532868@qq.com");

        // 发送邮件
        emailSender.sendHtmlMail("1036532868@qq.com",
                "RippleAI项目可用密钥数量已降至警戒线下!",
                "RippleAI项目目前可用ChatGPT密钥数量已降至警戒线下！<br>" +
                        "当前可用数量：" + size + "<br>" +
                        "警戒线数量：" + warningLine);
    }

    /**
     * 停用密钥
     *
     * @param cache        cache
     * @param responseBody 返回数据
     * @author gdk
     * @since 2023/5/29 17:02
     */
    public void disableKey(AIApiKeyCache cache, String responseBody) {
        Long removeCount = redis.opsForSet().remove(CacheConstants.AI_API_KEY_HASH_KEY, cache);
        AIApiKey entity = AIApiKeyStruct.INSTANCE.cache2Entity(cache);
        if (!Objects.isNull(removeCount) && removeCount == 1) {
            entity.setDisableReason(String.format("异常返回数据：%s", responseBody));
            entity.setUpdateBy("0");
            entity.setUpdateTime(new Date());
            entity.setUpdateName("系统");
            // mysql删除
            if (aiApiKeyMapper.disable(entity) != 1) {
                log.error("停用密钥失败，{}", cache);
            }

            Long size = redis.opsForSet().size(CacheConstants.AI_API_KEY_HASH_KEY);
            Integer warningLine = Integer.valueOf(sysConfigService.selectConfigByKey(SysConfigConstants.AI_CHAT_API_KEY_WARNING_LINE));
            if (size <= warningLine) {
                emailNotify(warningLine, size);
            }
        }
    }
}
